/**
 * Player - 玩家角色类
 * 继承Entity，实现跑酷游戏中的玩家控制逻辑
 */

import { Entity, EntityType, type EntityOptions } from './Entity'
import { AnimationManager } from './AnimationManager'
import { Animation } from './Animation'
import { Sprite } from './Sprite'
import type { Character } from './Character'
import { CharacterAbilityType } from './Character'

export enum PlayerState {
  RUNNING = 'running',
  JUMPING = 'jumping',
  SLIDING = 'sliding',
  FALLING = 'falling',
  DEAD = 'dead'
}

export enum PlayerLane {
  LEFT = 0,
  CENTER = 1,
  RIGHT = 2
}

export interface PlayerOptions extends Omit<EntityOptions, 'type'> {
  jumpForce?: number
  gravity?: number
  runSpeed?: number
  slideSpeed?: number
  slideDuration?: number
  maxHealth?: number
  laneWidth?: number
  groundY?: number
  character?: Character
}

export interface PlayerStats {
  score: number
  distance: number
  coinsCollected: number
  powerUpsCollected: number
  obstaclesAvoided: number
}

export class Player extends Entity {
  // 物理属性
  private jumpForce: number
  private gravity: number
  private runSpeed: number
  private slideSpeed: number
  private slideDuration: number
  private groundY: number
  private laneWidth: number

  // 状态管理
  public state: PlayerState = PlayerState.RUNNING
  public previousState: PlayerState = PlayerState.RUNNING
  public currentLane: PlayerLane = PlayerLane.CENTER
  public targetLane: PlayerLane = PlayerLane.CENTER
  
  // 生命值和统计
  public health: number
  public maxHealth: number
  public stats: PlayerStats

  // 角色系统
  public character: Character | null = null

  // 动画和时间控制
  private slideTimer: number = 0
  private isGrounded: boolean = true
  private laneTransitionSpeed: number = 8 // pixels per frame
  // State change time tracking (reserved for future use)
  // private stateChangeTime: number = 0
  private animationManager: AnimationManager

  // 输入缓冲
  private inputBuffer: { action: string; timestamp: number }[] = []
  private inputBufferDuration: number = 100 // ms

  constructor(options: PlayerOptions) {
    super({
      ...options,
      type: EntityType.PLAYER
    })

    // 初始化物理属性
    this.jumpForce = options.jumpForce || -400 // 负值表示向上
    this.gravity = options.gravity || 1200 // 重力加速度
    this.runSpeed = options.runSpeed || 200
    this.slideSpeed = options.slideSpeed || 150
    this.slideDuration = options.slideDuration || 800 // ms
    this.groundY = options.groundY || 300
    this.laneWidth = options.laneWidth || 100

    // 设置角色
    this.character = options.character || null

    // 初始化生命值（应用角色修饰符）
    this.maxHealth = options.maxHealth || 3
    if (this.character) {
      this.maxHealth += this.character.stats.health - 3 // 基础生命值为3
    }
    this.health = this.maxHealth

    // 应用角色属性修饰符
    this.applyCharacterModifiers()

    // 初始化统计数据
    this.stats = {
      score: 0,
      distance: 0,
      coinsCollected: 0,
      powerUpsCollected: 0,
      obstaclesAvoided: 0
    }

    // 初始化动画系统
    this.animationManager = new AnimationManager()
    this.initializeAnimations()

    // 设置初始位置
    this.updateLanePosition()
    this.y = this.groundY - this.height
  }

  /**
   * 更新玩家逻辑
   */
  update(deltaTime: number): void {
    if (!this.active || this.state === PlayerState.DEAD) {
      return
    }

    // 处理输入缓冲
    this.processInputBuffer()

    // 更新状态机
    this.updateStateMachine(deltaTime)

    // 应用物理
    this.applyPlayerPhysics(deltaTime)

    // 更新车道位置
    this.updateLaneTransition(deltaTime)

    // 更新动画
    this.updateAnimations(deltaTime)

    // 更新统计数据
    this.updateStats(deltaTime)

    // 检查边界
    this.checkBounds()
  }

  /**
   * 跳跃
   */
  jump(): boolean {
    // 检查是否可以跳跃
    if (!this.canJump()) {
      this.addInputToBuffer('jump')
      return false
    }

    this.changeState(PlayerState.JUMPING)
    this.velocity.y = this.jumpForce
    this.isGrounded = false
    
    return true
  }

  /**
   * 滑铲
   */
  slide(): boolean {
    // 检查是否可以滑铲
    if (!this.canSlide()) {
      this.addInputToBuffer('slide')
      return false
    }

    this.changeState(PlayerState.SLIDING)
    this.slideTimer = this.slideDuration
    this.velocity.x = this.slideSpeed
    
    // 滑铲时降低高度
    this.height = this.height * 0.5
    this.y = this.groundY - this.height

    return true
  }

  /**
   * 向左移动
   */
  moveLeft(): boolean {
    if (this.targetLane > PlayerLane.LEFT) {
      this.targetLane = this.targetLane - 1
      return true
    }
    return false
  }

  /**
   * 向右移动
   */
  moveRight(): boolean {
    if (this.targetLane < PlayerLane.RIGHT) {
      this.targetLane = this.targetLane + 1
      return true
    }
    return false
  }

  /**
   * 受到伤害
   */
  takeDamage(damage: number = 1): void {
    if (this.state === PlayerState.DEAD) {
      return
    }

    this.health = Math.max(0, this.health - damage)
    
    if (this.health <= 0) {
      this.die()
    }
  }

  /**
   * 治疗
   */
  heal(amount: number = 1): void {
    this.health = Math.min(this.maxHealth, this.health + amount)
  }

  /**
   * 死亡
   */
  die(): void {
    this.changeState(PlayerState.DEAD)
    this.velocity.x = 0
    this.velocity.y = 0
    this.health = 0
  }

  /**
   * 重置玩家状态
   */
  reset(): void {
    this.health = this.maxHealth
    this.state = PlayerState.RUNNING
    this.previousState = PlayerState.RUNNING
    this.currentLane = PlayerLane.CENTER
    this.targetLane = PlayerLane.CENTER
    this.velocity.x = 0
    this.velocity.y = 0
    this.slideTimer = 0
    this.isGrounded = true
    this.active = true
    this.visible = true
    
    // 重置统计数据
    this.stats = {
      score: 0,
      distance: 0,
      coinsCollected: 0,
      powerUpsCollected: 0,
      obstaclesAvoided: 0
    }

    // 重置位置
    this.updateLanePosition()
    this.y = this.groundY - this.height
  }

  /**
   * 设置角色
   */
  setCharacter(character: Character): void {
    this.character = character
    this.applyCharacterModifiers()
  }

  /**
   * 获取角色
   */
  getCharacter(): Character | null {
    return this.character
  }

  /**
   * 应用角色修饰符
   */
  private applyCharacterModifiers(): void {
    if (!this.character || !this.character.stats) return

    // 应用角色基础属性
    this.runSpeed = this.character.stats.baseSpeed
    this.jumpForce = -this.character.stats.jumpForce // 负值表示向上
    this.slideSpeed = this.character.stats.slideSpeed
    this.slideDuration = this.character.stats.slideDuration

    // 应用角色能力修饰符
    if (this.character.abilities) {
      this.character.abilities.forEach(ability => {
        switch (ability.type) {
          case CharacterAbilityType.SPEED:
            this.runSpeed *= ability.value
            break
          case CharacterAbilityType.JUMP:
            this.jumpForce *= ability.value
            break
          case CharacterAbilityType.SLIDE:
            this.slideSpeed *= ability.value
            this.slideDuration *= ability.value
            break
        }
      })
    }
  }

  /**
   * 获取当前状态信息
   */
  getStateInfo(): {
    state: PlayerState
    previousState: PlayerState
    isGrounded: boolean
    currentLane: PlayerLane
    health: number
    stats: PlayerStats
    character: Character | null
  } {
    return {
      state: this.state,
      previousState: this.previousState,
      isGrounded: this.isGrounded,
      currentLane: this.currentLane,
      health: this.health,
      stats: { ...this.stats },
      character: this.character
    }
  }

  /**
   * 检查是否可以跳跃
   */
  private canJump(): boolean {
    return this.isGrounded && 
           (this.state === PlayerState.RUNNING || this.state === PlayerState.SLIDING)
  }

  /**
   * 检查是否可以滑铲
   */
  private canSlide(): boolean {
    return this.isGrounded && 
           (this.state === PlayerState.RUNNING || this.state === PlayerState.JUMPING)
  }

  /**
   * 改变状态
   */
  private changeState(newState: PlayerState): void {
    if (this.state !== newState) {
      this.previousState = this.state
      this.state = newState
      // this.stateChangeTime = Date.now()
    }
  }

  /**
   * 更新状态机
   */
  private updateStateMachine(deltaTime: number): void {
    switch (this.state) {
      case PlayerState.RUNNING:
        this.velocity.x = this.runSpeed
        break

      case PlayerState.JUMPING:
        if (this.isGrounded && this.velocity.y >= 0) {
          this.changeState(PlayerState.RUNNING)
        }
        break

      case PlayerState.SLIDING:
        this.slideTimer -= deltaTime
        if (this.slideTimer <= 0) {
          this.endSlide()
        }
        break

      case PlayerState.FALLING:
        if (this.isGrounded) {
          this.changeState(PlayerState.RUNNING)
        }
        break

      case PlayerState.DEAD:
        // 死亡状态不做任何处理
        break
    }
  }

  /**
   * 应用玩家物理
   */
  private applyPlayerPhysics(deltaTime: number): void {
    const deltaSeconds = deltaTime / 1000

    // 应用重力
    if (!this.isGrounded) {
      this.velocity.y += this.gravity * deltaSeconds
    }

    // 更新位置
    this.y += this.velocity.y * deltaSeconds

    // 检查地面碰撞，但只有在玩家还活着时才限制到地面
    if (this.state !== PlayerState.DEAD && this.y >= this.groundY - this.height) {
      this.y = this.groundY - this.height
      this.velocity.y = 0
      this.isGrounded = true
      
      if (this.state === PlayerState.JUMPING) {
        this.changeState(PlayerState.RUNNING)
      }
    } else {
      this.isGrounded = false
      if (this.state === PlayerState.RUNNING && this.velocity.y > 0) {
        this.changeState(PlayerState.FALLING)
      }
    }
  }

  /**
   * 更新车道转换
   */
  private updateLaneTransition(deltaTime: number): void {
    if (this.currentLane !== this.targetLane) {
      const targetX = this.getLaneX(this.targetLane)
      const diff = targetX - this.x
      const moveDistance = this.laneTransitionSpeed * (deltaTime / 16.67) // 标准化到60fps

      if (Math.abs(diff) <= moveDistance) {
        this.x = targetX
        this.currentLane = this.targetLane
      } else {
        this.x += Math.sign(diff) * moveDistance
      }
    }
  }

  /**
   * 获取车道X坐标
   */
  private getLaneX(lane: PlayerLane): number {
    const centerX = 400 // 假设画布宽度800，中心在400
    return centerX + (lane - 1) * this.laneWidth - this.width / 2
  }

  /**
   * 更新车道位置
   */
  private updateLanePosition(): void {
    this.x = this.getLaneX(this.currentLane)
  }

  /**
   * 结束滑铲
   */
  private endSlide(): void {
    // 恢复原始高度
    const originalHeight = this.height * 2
    this.height = originalHeight
    this.y = this.groundY - this.height
    
    this.changeState(PlayerState.RUNNING)
  }

  /**
   * 添加输入到缓冲区
   */
  private addInputToBuffer(action: string): void {
    this.inputBuffer.push({
      action,
      timestamp: Date.now()
    })
  }

  /**
   * 处理输入缓冲
   */
  private processInputBuffer(): void {
    const currentTime = Date.now()
    
    // 清理过期的输入
    this.inputBuffer = this.inputBuffer.filter(
      input => currentTime - input.timestamp <= this.inputBufferDuration
    )

    // 处理有效的输入
    for (let i = this.inputBuffer.length - 1; i >= 0; i--) {
      const input = this.inputBuffer[i]
      if (input.action === 'jump' && this.canJump()) {
        this.velocity.y = this.jumpForce
        this.isGrounded = false
        this.changeState(PlayerState.JUMPING)
        this.inputBuffer.splice(i, 1)
        break
      } else if (input.action === 'slide' && this.canSlide()) {
        this.changeState(PlayerState.SLIDING)
        this.slideTimer = this.slideDuration
        this.velocity.x = this.slideSpeed
        this.height = this.height * 0.5
        this.y = this.groundY - this.height
        this.inputBuffer.splice(i, 1)
        break
      }
    }
  }

  /**
   * 更新统计数据
   */
  private updateStats(deltaTime: number): void {
    if (this.state !== PlayerState.DEAD) {
      this.stats.distance += (this.velocity.x * deltaTime) / 1000
      this.stats.score = Math.floor(this.stats.distance * 10)
    }
  }

  /**
   * 检查边界
   */
  private checkBounds(): void {
    // 如果玩家掉出屏幕底部，则死亡
    if (this.y > this.groundY + 100) {
      this.die()
    }
  }

  /**
   * 初始化动画
   */
  private initializeAnimations(): void {
    // 创建默认的彩色矩形精灵（用于测试）
    const canvas = document.createElement('canvas')
    const ctx = canvas.getContext('2d')
    if (!ctx) {
      console.warn('Could not get canvas context for animation initialization')
      return
    }
    
    canvas.width = this.width * 4 // 4帧动画
    canvas.height = this.height

    // 绘制跑步动画帧（4帧，颜色渐变）
    const runningColors = ['#4CAF50', '#66BB6A', '#4CAF50', '#388E3C']
    for (let i = 0; i < 4; i++) {
      ctx.fillStyle = runningColors[i]
      ctx.fillRect(i * this.width, 0, this.width, this.height)
    }

    const runningImage = new Image()
    runningImage.src = canvas.toDataURL()
    
    // 创建跑步精灵
    const runningSprite = Sprite.createFromSpriteSheet(
      runningImage,
      this.width,
      this.height,
      4
    )

    // 创建跳跃精灵（单帧）
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    ctx.fillStyle = '#2196F3'
    ctx.fillRect(0, 0, this.width, this.height)
    
    const jumpingImage = new Image()
    jumpingImage.src = canvas.toDataURL()
    const jumpingSprite = Sprite.createSingle(jumpingImage)

    // 创建滑铲精灵（单帧）
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    ctx.fillStyle = '#FF9800'
    ctx.fillRect(0, 0, this.width, this.height * 0.5)
    
    const slidingImage = new Image()
    slidingImage.src = canvas.toDataURL()
    const slidingSprite = Sprite.createSingle(slidingImage)

    // 创建死亡精灵（单帧）
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    ctx.fillStyle = '#9E9E9E'
    ctx.fillRect(0, 0, this.width, this.height)
    
    const deadImage = new Image()
    deadImage.src = canvas.toDataURL()
    const deadSprite = Sprite.createSingle(deadImage)

    // 创建动画
    const runningAnimation = Animation.createLoop('running', runningSprite, 150) // 150ms per frame
    const jumpingAnimation = Animation.createOnce('jumping', jumpingSprite, 100)
    const slidingAnimation = Animation.createOnce('sliding', slidingSprite, 100)
    const fallingAnimation = Animation.createOnce('falling', jumpingSprite, 100)
    const deadAnimation = Animation.createOnce('dead', deadSprite, 100)

    // 添加动画到管理器
    this.animationManager.addAnimation(runningAnimation)
    this.animationManager.addAnimation(jumpingAnimation)
    this.animationManager.addAnimation(slidingAnimation)
    this.animationManager.addAnimation(fallingAnimation)
    this.animationManager.addAnimation(deadAnimation)

    // 设置默认动画
    this.animationManager.setDefaultAnimation('running')

    // 添加动画转换规则
    this.animationManager.addTransition({
      from: 'running',
      to: 'jumping',
      condition: () => this.state === PlayerState.JUMPING,
      priority: 10
    })

    this.animationManager.addTransition({
      from: 'running',
      to: 'sliding',
      condition: () => this.state === PlayerState.SLIDING,
      priority: 10
    })

    this.animationManager.addTransition({
      from: 'jumping',
      to: 'falling',
      condition: () => this.state === PlayerState.FALLING,
      priority: 5
    })

    this.animationManager.addTransition({
      from: 'falling',
      to: 'running',
      condition: () => this.state === PlayerState.RUNNING,
      priority: 5
    })

    this.animationManager.addTransition({
      from: 'sliding',
      to: 'running',
      condition: () => this.state === PlayerState.RUNNING,
      priority: 5
    })

    // 死亡动画具有最高优先级
    const states = ['running', 'jumping', 'sliding', 'falling']
    states.forEach((from: string) => {
      this.animationManager.addTransition({
        from,
        to: 'dead',
        condition: () => this.state === PlayerState.DEAD,
        priority: 100
      })
    })
  }

  /**
   * 更新动画
   */
  private updateAnimations(deltaTime: number): void {
    this.animationManager.update(deltaTime)
  }

  /**
   * 渲染玩家（重写Entity的render方法以使用动画）
   */
  render(ctx: CanvasRenderingContext2D): void {
    if (!this.visible) return

    // 使用动画管理器渲染
    this.animationManager.render(ctx, this.x, this.y, this.width, this.height)
  }

  /**
   * 获取当前动画名称
   */
  getCurrentAnimationName(): string | null {
    return this.animationManager.getCurrentAnimationName()
  }

  /**
   * 获取动画管理器（用于测试）
   */
  getAnimationManager(): AnimationManager {
    return this.animationManager
  }

  /**
   * 获取默认颜色
   */
  protected getDefaultColor(): string {
    switch (this.state) {
      case PlayerState.JUMPING:
        return '#2196F3' // 蓝色
      case PlayerState.SLIDING:
        return '#FF9800' // 橙色
      case PlayerState.DEAD:
        return '#9E9E9E' // 灰色
      default:
        return '#4CAF50' // 绿色
    }
  }
}